#ifndef UTILS_CPP_
#define UTILS_CPP_

#define DEBUG 0

#include "Utils.h"
#include <fstream>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <stdlib.h>

using namespace std;

int readDppmSpec(char* filePath, int &numAct, int &T, int* &numPreds, int** &Preds, int* &numModes, int** &ModesCosts, int** &ModesTimes){

	ifstream file;
	string line;
	file.open(filePath);

	if (!file.is_open()){
		return -1;
	}

	if (getline(file,line) == 0){
		return -1;
	}

	int lineNumber = 0;

	//Leer fila1: Numero de actividades y deadline
	sscanf(line.data(),"%d %d",&numAct,&T);

	lineNumber++;
	if (DEBUG){
		cout << lineNumber << ":\"" << line.data() << "\"\n";
		cout << "    numAct = \"" << numAct << "\"\n";
		cout << "    T = \"" << T << "\"\n";
		cout << "--------------------------------\n\n";
	}

	getline(file,line);
	getline(file,line);
	lineNumber++;
	lineNumber++;

	//Inicializar arreglo de predecesores
	Preds = new int*[numAct];
	numPreds = new int[numAct];

	//auxiliares
	int pred;
	int preds[1000];
	char* lineCopy;
	char* rest;

	for (int i = 0; i < numAct; i++){

		getline(file,line);
		lineCopy = new char[strlen(line.data()) + 1];
		strcpy(lineCopy, line.data());
		rest = lineCopy;

		numPreds[i] = 0;

		if (strcmp(rest," .")){
			do{
				sscanf(rest,"%d %[^\n]",&pred,rest);
				preds[numPreds[i]] = pred;
				numPreds[i]++;
			}while (strcmp(rest,"."));
		}

		if (numPreds[i] == 0){
			Preds[i] = NULL;
		}
		else{
			Preds[i] = new int[numPreds[i]];

			for(int j = 0; j < numPreds[i]; j++){
				Preds[i][j] = preds[j];
			}
		}

		delete [] lineCopy;

		lineNumber++;
		if (DEBUG){
			cout << lineNumber << ":\"" << line.data() << "\"\n";
			cout << "    cantPreds = \"" << numPreds[i] << "\"\n";
			cout << "--------------------------------\n\n";
		}
	}


	getline(file,line);
	getline(file,line);
	lineNumber++;
	lineNumber++;


	//Inicializar arreglos de modos
	ModesCosts = new int*[numAct];
	ModesTimes = new int*[numAct];
	numModes = new int[numAct];

	//auxiliares
	int cost, time;
	int modestimes[1000];
	int modescosts[1000];

	for (int i = 0; i < numAct; i++){
		getline(file,line);
		lineCopy = new char[strlen(line.data()) + 1];
		strcpy(lineCopy, line.data());
		rest = lineCopy;

		numModes[i] = 0;

		if (strcmp(rest," .")){
			do{
				sscanf(rest,"(%d,%d) %[^\n]",&cost,&time,rest);
				modescosts[numModes[i]] = cost;
				modestimes[numModes[i]] = time;
				numModes[i]++;
			}while (strcmp(rest,"."));
		}

		if (numModes[i] == 0){
			ModesCosts = NULL;
			ModesTimes = NULL;
		}
		else{
			ModesCosts[i] = new int[numModes[i]];
			ModesTimes[i] = new int[numModes[i]];

			for(int j = 0; j < numModes[i]; j++){
				ModesCosts[i][j] = modescosts[j];
				ModesTimes[i][j] = modestimes[j];
			}
		}

		delete [] lineCopy;

		lineNumber++;
		if (DEBUG){
			cout << lineNumber << ":\"" << line.data() << "\"\n";
			cout << "    cantModes = \"" << numModes[i] << "\"\n";
			cout << "--------------------------------\n\n";
		}
	}

	file.close();

	return 0;
}

pthread_t createThread(int (*start_routine) ()) {
    pthread_attr_t attr;

    if (pthread_attr_init(&attr)) {
        perror("Error at thread's attribute initialization time (Util,161)\n");
    }

    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    pthread_t id;

    if (pthread_create(&id, &attr, (void*(*)(void*)) start_routine, NULL)) {
        perror("Error at thread creation time (Util,169)\n");
    }
    if (pthread_attr_destroy(&attr)) {
        perror("Error at thread's attribute detruction time (Util,172)\n");
    }

    return id;
}

void debugPrinter(int identacion, int rank, const char * archivo, int linea, const char * desc){
//
	stringstream output;

	for (int i = 0; i < identacion; i++)
		output << "\t";

	output << "DEBUG  " << rank << "  " << archivo << ":" << linea << " -  " << desc << "\n";

	cout << output.str();
}

void debugPrinter(int identacion, int rank, const char * archivo, int linea, const char * desc, const char * var1Name, double var1){
//
	stringstream output;

	for (int i = 0; i < identacion; i++)
		output << "\t";

	output << "DEBUG  " << rank << "  " << archivo << ":" << linea << " -  " << desc << "   " << var1Name << "=" << var1 << "\n";

	cout << output.str();
}

void debugPrinter(int identacion, int rank, const char * archivo, int linea, const char * desc,  const char * var1Name, double var1, const char * var2Name, double var2){

	stringstream output;

	for (int i = 0; i < identacion; i++)
		output << "\t";

	output << "DEBUG  " << rank << "  " << archivo << ":" << linea << " -  " << desc << "   " << var1Name << "=" << var1 << "   " << var2Name << "=" << var2 << "\n";

	cout << output.str();

}

void debugPrinter(int identacion, int rank, const char * archivo, int linea, const char * desc,  const char * var1Name, int var1, const char * var2Name, int var2){

	stringstream output;

	for (int i = 0; i < identacion; i++)
		output << "\t";

	output << "DEBUG  " << rank << "  " << archivo << ":" << linea << " -  " << desc << "   " << var1Name << "=" << var1 << "   " << var2Name << "=" << var2 << "\n";

	cout << output.str();

}

void debugPrinter(int identacion, int rank, const char * archivo, int linea, const char * desc,
		const char * var1Name, double var1, const char * var2Name, double var2, const char * var3Name, double var3){

	for (int i = 0; i < identacion; i++)
		cout << "\t";

	cout << "DEBUG  " << rank << "  " << archivo << ":" << linea << " -  " << desc << "   " << var1Name << "=" << var1 << "   " << var2Name << "=" << var2 << "   " << var3Name << "=" << var3 <<endl;


}

#endif /* UTILS_CPP_ */
